﻿using Abp.Authorization;
using Abp.Domain.Repositories;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using SOEI.Solution.Application.Contracts.Customized.RegulatoryMange;
using SOEI.Solution.Application.Contracts.Integratedes.SignContracts;
using SOEI.Solution.CommonOthers.Pdf.DomainService;
using SOEI.Solution.CommonOthers.Pdf.StructEntities;
using SOEI.Solution.Customized;
using SOEI.Solution.DomainEntities.RegulatoryMange;
using SOEI.Solution.DomainEntities.RegulatoryMange.DomainService;
using SOEI.Solution.Integratedes.ElectronicSignet.DomainService;
using SOEI.Solution.Integratedes.Organization.DomainService;
using SOEI.Solution.StructEntities.Contracts;
using SOEI.Solution.ThirdParty.ESignClient.Models;
using SOEI.Solution.ThirdParty.ESignClient.Models.Notifies;
/*
合同签署专用
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ThirdParty.ESignClient;

namespace SOEI.Solution.Integratedes.SignContracts
{
	/// <summary>
	/// 【扩展模块】  <br/>
	/// 【功能描述】  ：合同签署专用<br/>
	/// 【创建日期】  ：2020.09.30 <br/>
	/// 【开发人员】  ：static残影<br/>
	///</summary>
	[AbpAuthorize]
	[ApiExplorerSettings(GroupName = "Manager", IgnoreApi = false)]
	public class SignContractAppService: SolutionAppServiceBase, ISignContractAppService
	{
		/// <summary>
		///【Agreement】仓储层
		/// </summary>
		private readonly IRepository<AgreementBoth, string> _agreementBothRepository;

		/// <summary>
		///【Agreement】领域服务
		/// </summary>
		private readonly IAgreementManager _agreementManager;

		/// <summary>
		///【机构领域】 机构领域服务
		/// </summary>
		private readonly IOEconomyOrganiManager _oeconomyorganiManager;

		/// <summary>
		/// PDF接口
		/// </summary>
		public IPdfManager _pdfManager;

		/// <summary>
		/// 合同处理接口
		/// </summary>
		public IContractManager _contractManager;

		/// <summary>
		/// 【电子签章】电子签章领域服务
		/// </summary>
		private readonly IOrgSignetManager _orgSignetManager;

		/// <summary>
		/// 电子签章接口
		/// </summary>
		private readonly IESignManager _eSignManager;

		public SignContractAppService(
			
			
			IRepository<AgreementBoth, string> agreementBothRepository,
			IOEconomyOrganiManager oeconomyorganiManager,
			IPdfManager pdfManager,
			IOrgSignetManager orgSignetManager,
			IContractManager contractManager,
			IESignManager eSignManager
		)
		{
		
			_agreementBothRepository = agreementBothRepository;
			_oeconomyorganiManager = oeconomyorganiManager;
			_pdfManager = pdfManager;
			_orgSignetManager = orgSignetManager;
			_contractManager = contractManager;
			_eSignManager = eSignManager;
		}

		/// <summary>
		/// 发送资金监管合同通知签署信息，会根据手机号邀请完成流程（签署过的不会在发送）
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task SendRegulatoryContractForBothsNotify(BothsNotifyInput input)
		{
			//1. 收集当前登录用户信息和企业信息当前企业为发起人
			var userEntity = await this.GetPersonChecker();
			//2. 当前登录的机构信息
			var organiEntity = await this._oeconomyorganiManager.FindByIdAsync(userEntity.OriginalNumber);
			//3. 判断是否有权进行合同发起
			var orgSignEntity = await _orgSignetManager.FindByPersonIDAsync(organiEntity.GLYBH);
			//4. 获取合同文件内容
			var pdfParam = new PdfParam()
			{
				Id = input.PdfId
			};
			var PdfBuffer = await this._pdfManager.GetPdfAsync(pdfParam);
			//5. 获取合同签署相关方集合
			var entityList = await this._agreementBothRepository.GetAll()
						.AsNoTracking()
						.Where(x => x.JGXYBH == input.Id)
						.Where(x => x.SignetStatus == ESignetStatus.Default) // 获取没有完成的
						.Where(x => x.SFLBDM == "02")
						.OrderBy(x => x.SFLBDM)
						.ToListAsync();
			//6.创建合同数据准备
			var contractEntity = new ContractEntity();
			contractEntity.AliasName = "二手房资金监管协议";
			contractEntity.FileName = "二手房资金监管协议.pdf"; // 必须是PDF文件
			contractEntity.FileBuffer = PdfBuffer;  // 文件二进制数据
			contractEntity.Flow.AccountId = orgSignEntity.AccountID;  // 流程发起人为 当前登录的所属机构用户（其实应该是资金监管机构）
			contractEntity.Flow.businessScene = "资金监管合同";
			contractEntity.Flow.OrganiAccountID = orgSignEntity.ORGID; // 发起方所属机构的账号
			//int pY = 0;
			foreach (var item in entityList)
			{
				// 创建账号
				await this.CreateAccountAsync(item);
				// 回调实体
				var thirdNoticeEntity = new ThirdNoticeEntity<string> {
					 ConnectionId = input.ConnectionId,
					 Data = item.Id
				};
				// 设置坐标关键字查询 (不同的)
				contractEntity.Searches.Add(new SearchEntity { 
					 AccountID = item.AccountID,
					 ThirdOrderNo = thirdNoticeEntity.ToJson(),
					 Keyword  = this.GetKeyword(item), // 这里根据不同的签署人或者类型，设置不同的关键字 比如 甲方，乙方 
					  OffsetX = 150,  // 关键字找到后的盖章偏移量 X
					  OffsetY = 30,   // 关键字找到后的盖章偏移量 Y
					    Order = this.GetFlowOrder(item)     // 签署区顺序，默认1,且不小于1，顺序越小越先处理 (我们根据)
				});

				// 配置签署相关方(根据类型和关键字查找签署位置)
				/*contractEntity.Manuals.Add(new ManualEntity { 
					AccountID = item.AccountID, 
					PosPage = 1, // 印章盖到第几页下面是坐标
					PosX = 500,  
					PosY = 500 + pY,
					ThirdOrderNo = thirdNoticeEntity.ToJson() // 签署成功回调参数
				});*/

				//pY += 300;
			}
			// 发起合同
			await this._contractManager.CreateRegulatorContract(contractEntity);
		}

		/// <summary>
		/// 获取关键字
		/// </summary>
		/// <param name="item"></param>
		/// <returns></returns>
		protected string GetKeyword(AgreementBoth item) 
		{
			switch (item.SFLBDM) 
			{
				case "01": // 第三方自动签章
					return "#{监管电子签章}";
				case "02": // 甲方
					return "#{甲方电子签章}";
				case "04": // 乙方
					return "#{乙方电子签章}";
				default:
					return string.Empty;
			}
		}

		/// <summary>
		/// 获取签署顺序
		/// </summary>
		/// <param name="item"></param>
		/// <returns></returns>
		protected int GetFlowOrder(AgreementBoth item)
		{
			switch (item.SFLBDM)
			{
				case "02": // 甲方
					return 1;
				case "04": // 乙方
					return 2;
				default:
					return 0;
			}
		}

		/// <summary>
		/// 【 Edit by Hua 】创建账号如果存在则不用创建了
		/// </summary>
		/// <returns></returns>
		protected async Task CreateAccountAsync(AgreementBoth item)
		{
			var AccountEntity = new AccountEntity
			{
				AccountID = item.AccountID,
				ThirdPartyUserId = item.LXDH,
				Mobile = item.LXDH,
				IdNumber = item.ZJHM,
				Name = item.XM
			};

			// 如果已经存在账号编号就不需要创建了
			if (!string.IsNullOrEmpty(item.AccountID))
			{
				// 更新一下
				await _eSignManager.UpdateAccountAsync(AccountEntity);
				return;
			}

			var AccountResult = await _eSignManager.GetCreateAccountAsync(AccountEntity);
			item.AccountID = AccountResult.AccountID;
			await this._agreementBothRepository.UpdateAsync(item);
		}


	}
}
